package cn.demoncat.util.lang.entity;

import cn.demoncat.util.lang.StringUtil;
import cn.demoncat.util.lang.constant.MysqlConstant;
import cn.demoncat.util.lang.constant.StringConstant;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

/**
 * Mysql查询条件
 *
 * @author 延晓磊
 * @since 2021年11月24日
 */
@Data
public class MysqlQuery {

    // 查询字段
    private String column;
    // 查询条件
    private MapSo condition = MapSo.getInstance();
    // 分组
    private String group = StringConstant.EMPTY;
    // 排序
    private String order = StringConstant.EMPTY;
    // 限制
    private String limit = StringConstant.EMPTY;
    // 子查询
    private MysqlQuery child;



    /**
     * 添加查询字段
     *
     * @param columns   查询字段
     * @return column1,column_2
     */
    public MysqlQuery addColumn(String ...columns){
        for (String s : columns) {
            this.appendColumn(s);
        }
        return this;
    }

    /**
     * 添加查询字段
     *
     * @param column
     * @param alias     别名
     * @return column AS alias
     */
    public MysqlQuery addColumnAs(String column, String alias){
        return addColumn(column +" AS "+ alias);
    }

    /**
     * 添加查询字段
     *
     * @param columns   查询字段，如果不包含"AS"且包含"_"则自动拼接AS驼峰名
     * @return column1 AS column1,column_name2 AS columnName2
     */
    public MysqlQuery addColumnAsHump(String ...columns){
        for (String s : columns) {
            this.appendColumn(this.appendColumnAlias(s));
        }
        return this;
    }

    /**
     * 添加查询字段 - 函数
     *
     * @param function  函数：MysqlConstant.Function
     * @param alias     别名
     * @param column    字段，参数
     * @return FUNCTION(column) AS alias
     */
    public MysqlQuery addColumnFunction(String function, String alias, String ...column){
        return addColumnAs(String.format(function, column), alias);
    }

    /**
     * 添加查询字段 - COUNT
     *
     * @return COUNT(1) AS count
     */
    public MysqlQuery addColumnCount(){
        return addColumnAs(MysqlConstant.GroupFunction.COUNT, "count");
    }

    /**
     * 添加查询字段 - SUM
     *
     * @param column    字段
     * @return SUM(column) AS sum
     */
    public MysqlQuery addColumnSum(String column){
        return addColumnFunction(MysqlConstant.GroupFunction.SUM, "sum", column);
    }

    /**
     * 添加查询字段 - SUM
     *
     * @param columns    字段
     * @return SUM(column) AS column
     */
    public MysqlQuery addColumnSums(String ...columns){
        for (String s : columns) {
            this.appendColumn(String.format(MysqlConstant.GroupFunction.SUM, s)  +" AS "+ s);
        }
        return this;
    }

    /**
     * 添加查询字段 - SUM(IF)
     *
     * @param column    字段
     * @return SUM(IF(condition,column,0)) AS sum
     */
    public MysqlQuery addColumnSumIf(String condition, String column){
        return addColumnSumIf(condition, column, "sum");
    }

    /**
     * 添加查询字段 - SUM(IF)
     *
     * @param column    字段
     * @return SUM(IF(condition,column,0)) AS alias
     */
    public MysqlQuery addColumnSumIf(String condition, String column, String alias){
        return addColumnFunction(MysqlConstant.GroupFunction.SUM_CONDITION, alias, condition, column);
    }

    /**
     * 添加查询字段 - DATE_FORMAT
     *
     * @param column    字段
     * @param format    日期格式：MysqlConstant.DateFormat
     * @return DATE_FORMAT(column,format) AS date
     */
    public MysqlQuery addColumnDate(String column, String format){
        return addColumnDate(column, String.format("'%s'", format), "date");
    }

    /**
     * 添加查询字段 - DATE_FORMAT
     *
     * @param column    字段
     * @param format    日期格式：MysqlConstant.DateFormat
     * @param alias     别名
     * @return DATE_FORMAT(column,format) AS alias
     */
    public MysqlQuery addColumnDate(String column, String format, String alias){
        return addColumnFunction(MysqlConstant.Function.DATE_FORMAT, alias, column, format);
    }

    /**
     * 添加查询条件
     *
     * @param kvs   属性,值
     * @return
     */
    public MysqlQuery addCondition(Object ... kvs){
        this.condition.add(kvs);
        return this;
    }

    /**
     * 添加分组
     *
     * @param group
     * @return
     */
    public MysqlQuery addGroup(String group){
        if (StringUtils.isBlank(this.group)) {
            this.group = " GROUP BY " + group;
        }else{
            this.group += "," + group;
        }
        return this;
    }

    /**
     * 设置排序
     *
     * @param order
     * @return
     */
    public MysqlQuery addOrder(String order){
        if (StringUtils.isBlank(this.order)) {
            this.order = " ORDER BY " + order;
        }else{
            this.order += "," + order;
        }
        return this;
    }

    /**
     * 设置Limit
     *
     * @param limit
     * @return
     */
    public MysqlQuery addLimit(int limit){
        this.limit = " LIMIT " + limit;
        return this;
    }

    /**
     * 添加子查询
     *
     * @param child
     * @return
     */
    public MysqlQuery addChild(MysqlQuery child){
        this.child = child;
        return this;
    }

    /**
     * 拼接查询字段
     *
     * @param column
     */
    private void appendColumn(String column){
        if (this.column == null) {
            this.column = column;
        }else{
            this.column += "," + column;
        }
    }

    /**
     * 拼接查询字段的别名
     *
     * @param column
     * @return column_column AS columnColumn
     */
    private String appendColumnAlias(String column){
        if (column.contains("AS") || !column.contains("_")) {
            return column;
        }
        return column +" AS "+ StringUtil.parseLineToHump(column);
    }
}

